package rss_GUI;

import java.awt.Toolkit;
import java.awt.Component;
import java.awt.event.KeyEvent;
import java.text.SimpleDateFormat;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.swing.DefaultListCellRenderer;
import javax.swing.RowSorter.SortKey;
import javax.swing.JComponent;
import javax.swing.JList;
import javax.swing.KeyStroke;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import rss_CODE.RadioStationSystem;
import rss_POJO.*;

/**
 *
 * @author RS-team
 */
public class GroupManagement extends javax.swing.JFrame {

    private static final String dateRenderer = "EEE d MMM y";  // πρότυπο ημερομηνίας για εμφάνιση ή ελεγχο στις φόρμες
    private static final Integer minimumArtists = 2;  // η απαίτηση για ελάχιστο πλήθος Καλλιτεχνών σε κάθε Συγκρότημα

    private final RadioStationSystem rss;
    private final EntityManager em;
    private final MainMenu mm;

    private final String frameTitle;

    private Boolean addORedit;  // false: κλήση για EDIT, true: κλήση για ADD
    private Boolean editStatus;  // βρισκόμαστε σε κατάσταση editing των πεδίων της φόρμας ή όχι
    private Integer fieldFocused;  // ποιο πεδίο της φόρμας είναι focused
    private String tempTxt;  // προσωρινή μεταβλητή String πεδίων
    private final MusicGroup tempMG;  // προσωρινά αποθηκευμένο MusicGroup
    private MusicGroup mg;
 

    /**
     * Creates new form GroupManagement
     */
    public GroupManagement(MainMenu mm) {
        this.rss = mm.getRSS();
        this.em = mm.getEM();
        this.mm = mm;
        this.addORedit = null;
        this.editStatus = false;
        this.fieldFocused = 0;
        this.mg = new MusicGroup();
        this.tempMG = new MusicGroup();
        this.tempTxt = "";
        initComponents();
        this.frameTitle = this.getTitle();
        jScrollPaneFORM.setVerticalScrollBarPolicy(jScrollPaneFORM.VERTICAL_SCROLLBAR_ALWAYS);
        // κατάργηση ανεπιθύμητης τύπου enter λειτουργίας του space key για το combo box cboxArtist
        cboxArtist.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE,0,false), "none");
        // αρχικοποίηση και καθαρισμός πεδίων φόρμας επεξεργασίας, reset combo box to top (το index -1 είναι το null)
        EnableDisableFields(false); cboxArtist.setSelectedIndex(0); ClearAllFields();
    }

    /* dynamic jpql query που αναζητά εγγραφή στο table MusicGroup βάσει δοθέντος πεδίου και τιμής πεδίου */
    private Boolean searchMusicGroup(String field, Object value) {
        try {
            if(addORedit) {
                // σε ADD mode, το αντικείμενο MusicGroup mg είναι καινούριο οπότε ελεγχω όλη τη ΒΔ
                em.createQuery("SELECT mg FROM MusicGroup mg WHERE mg." + field + "=:value", MusicGroup.class)
                        .setParameter("value", value).getSingleResult();
            } else {
                // σε EDIT mode, πρέπει η αναζήτηση να εξαιρεί το ίδιο αντικείμενο MusicGroup mg μέσω του primary key
                em.createQuery("SELECT mg FROM MusicGroup mg WHERE mg." + field + "=:value AND mg.musicgroupid!=:id", MusicGroup.class)
                        .setParameter("value", value).setParameter("id", mg.getMusicgroupid()).getSingleResult();
            }
            return true;  // η αναζήτηση ήταν επιτυχής αφού δεν συνέβει κάποιο σφάλμα
        } catch(NoResultException nrex) {
            // δεν βρέθηκε τίποτα, άρα η εγγραφή είναι μοναδική
            return false;
        } catch(Exception ex) {
            // γενικότερο σφάλμα σύνθεσης ή εκτέλεσης query αναζήτησης MusicGroup
            rss.criticalErrorBox(this, "σφάλμα query αναζήτησης MUSICGROUP " + field);
            // αγνοώντας οποιαδήποτε πιθανά νέα Exceptions προκύψουν,...
            try {
                em.close();  // οριστικό κλείσιμο EntityManager em
            } catch (Exception e) {
                // τίποτα πλέον, έτσι κι αλλιώς πάμε για κλείσιμο
            } finally {
                System.exit(4);  // έξοδος με errorlevel 4
                return null;  // άχρηστο αλλά αναγκαίο
            }
        } 
    }

    /* μέθοδος για πλήρη καθαρισμό των πεδίων και προετοιμασία του musicgroup τύπου MusicGroup για GarbageCollector */
    private void clearMusicGroup(MusicGroup musicgroup) {
        // clear όλα τα πεδία
        musicgroup.setName(null);
        musicgroup.setFormationdate(null);
        // clear όλες τις λίστες του αντικειμένου
        if(musicgroup.getAlbumCollection() != null) musicgroup.getAlbumCollection().clear(); musicgroup.setAlbumCollection(null);
        if(musicgroup.getArtistCollection() != null) musicgroup.getArtistCollection().clear(); musicgroup.setArtistCollection(null);
        musicgroup.setMusicgroupid(null);  // και τέλος το primary key
    }
    
    /* μέθοδος για καθαρισμό όλων των πεδίων της φόρμας επεξεργασίας */
    private void ClearAllFields() {
        txtName.setText("");
        txtFormationDate.setText("");
        cboxArtist.setSelectedIndex(-1);  // index -1 είναι το null
        if(listArtistsInMusicGroup == null)  // αν η λίστα Καλλιτεχνών που συνδέεται με τον πίνακα είναι null, δημιούργησε νέα empty
            listArtistsInMusicGroup = org.jdesktop.observablecollections.ObservableCollections.observableList(new ArrayList<Artist>());
        else listArtistsInMusicGroup.clear();  // αλλιώς απλά μηδένισε την ήδη υπάρχουσα
    }

    /* μέθοδος για αντιγραφή πεδίων σε MusicGroup toMG από MusicGroup fromMG */
    private void CopyAllFields(MusicGroup toMG, MusicGroup fromMG) {
        toMG.setName(fromMG.getName());
        toMG.setFormationdate(fromMG.getFormationdate());
        if(fromMG.getAlbumCollection() != null) {  // αν η πηγαία λίστα Άλμπουμ του fromMG δεν είναι null
            if(toMG.getAlbumCollection() == null)  // αν η λίστα προορισμού Άλμπουμ του toMG είναι null, δημιούργησε νέα empty list
                toMG.setAlbumCollection(org.jdesktop.observablecollections.ObservableCollections.observableList(new ArrayList<Album>()));
            toMG.getAlbumCollection().clear(); toMG.getAlbumCollection().addAll(fromMG.getAlbumCollection());  // καθάρισε και κάνε την αντιγραφή
        } else toMG.setAlbumCollection(null);  // αλλιώς θέσε null και την λίστα προορισμού του toMG
        if(fromMG.getArtistCollection() != null) {  // αν η πηγαία λίστα Καλλιτεχνών του fromMG δεν είναι null
            if(toMG.getArtistCollection() == null)  // αν η λίστα προορισμού Καλλιτεχνών του toMG είναι null, δημιούργησε νέα empty list
                toMG.setArtistCollection(org.jdesktop.observablecollections.ObservableCollections.observableList(new ArrayList<Artist>()));
            toMG.getArtistCollection().clear(); toMG.getArtistCollection().addAll(fromMG.getArtistCollection());  // καθάρισε και κάνε την αντιγραφή
        } else toMG.setArtistCollection(null);  // αλλιώς θέσε null και την λίστα προορισμού του toMG
        toMG.setMusicgroupid(fromMG.getMusicgroupid());  // και τέλος το primary key
    }
    
    /* μέθοδος για ενημέρωση πεδίων φόρμας με τις τιμές του επιλεγμένου αντικειμενου mg τύπου MusicGroup */
    private void UpdateAllFields() {
        txtName.setText(mg.getName() == null? "" : mg.getName());
        txtFormationDate.setText(mg.getFormationdate() == null? "" : new SimpleDateFormat(dateRenderer).format(mg.getFormationdate()));  // επιπλέον μορφοποίησε ημερομηνία
        if(listArtistsInMusicGroup == null)  // αν η λίστα Καλλιτεχνών που είναι συνδεδεμένη με τον πίνακα είναι null, δημιούργησε νέα empty list
            listArtistsInMusicGroup = org.jdesktop.observablecollections.ObservableCollections.observableList(new ArrayList<Artist>());
        else listArtistsInMusicGroup.clear();  // αλλιώς μηδένισε πρώτα την ήδη υπάρχουσα και αν η λίστα Καλλιτεχνών του mg δεν είναι κενή
        if(mg.getArtistCollection() != null) listArtistsInMusicGroup.addAll(mg.getArtistCollection()); // κάνε την αντιγραφή
    }
    
    /* σύγκριση πεδίων φόρμας επεξεργασίας με το επιλεγμένο αντικειμενο mg τύπου MusicGroup */
    private Boolean compareAllFields() {
        // σύγκρινε ένα ένα τα πεδία για διαφορές με τα αντίστοιχα του επιλεγμένου MusicGroup mg προσέχοντας πάντα τα nulls
        if(mg.getName() == null? !txtName.getText().isEmpty() : !txtName.getText().equals(mg.getName())) return false;
        if(rss.validateDate(txtFormationDate.getText(), dateRenderer) == null) return false;  // για την ημερομηνία επιπλέον έλεγχοι μορφοποίησης και εγκυρότητας
        else if(mg.getFormationdate() == null? !rss.validateDate(txtFormationDate.getText(), dateRenderer).isEmpty() : !rss.validateDate(txtFormationDate.getText(), dateRenderer).equals(new SimpleDateFormat(dateRenderer).format(mg.getFormationdate()))) return false;
        if(mg.getArtistCollection() == null? !(listArtistsInMusicGroup == null || listArtistsInMusicGroup.isEmpty()) : (listArtistsInMusicGroup != null? !mg.getArtistCollection().equals(listArtistsInMusicGroup) : true)) return false;  // αν οι λίστες δεν είναι κενές, σύγκρινέ τες
        return true;  // όλα τα πεδία ταυτίζονται
    }

    /* πραγματοποιεί ελέγχους σε όλα τα πεδία με πρόβλεψη αλλαγής nullable ή uniqueness κατάστασης από τα POJOs */
    private Boolean validateAllFields() {
        // έλεγχοι για το Name
        if(!txtName.getText().equals(txtName.getText().replace("\\",""))) {  // έλεγχος για ανεπιθύμητους \ χαρακτήρες
            if(!mm.getExpertMode()) { txtName.grabFocus(); rss.infoBox(this, "Δεν επιτρέπονται  \\  σε αλφαριθμητικά"); return false; }  // αν όχι σε ExpertMode
            else { mg.setName(txtName.getText().replace("\\","").trim()); }  // αλλιώς σιωπηλά αφαίρεσε ανεπιθύμητους \ χαρακτήρες και κενά κατέρωθεν του αλφαριθμητικού
        } else mg.setName(txtName.getText().trim());  // αφαίρεσε μόνο τα κενά εκατέρωθεν του αλφαριθμητικού
        if(mg.getName().isEmpty()) mg.setName(null);  // αν είναι κενό μηδένισέ το σε null
        if(mg.getName() != null && mg.getName().length() > rss.fieldLength(this, MusicGroup.class, "name")) {  // περιορισμός αλφαριθμητικού στο μήκος που δηλώνεται στο POJO
            mg.setName(mg.getName().substring(0, rss.fieldLength(this, MusicGroup.class, "name"))); }
        if(mg.getName() != null && rss.fieldUnique(this, MusicGroup.class, "name") && searchMusicGroup("name", mg.getName())) {  // δυνητικός έλεγχος μοναδικότητας με query
            txtName.grabFocus(); rss.warningBox(this, "η ΕΠΩΝΥΜΙΑ ΣΥΓΚΡΟΤΗΜΑΤΟΣ που εισάγατε υπάρχει ήδη    "); return false; }
        if(mg.getName() == null && !rss.fieldNullable(this, MusicGroup.class, "name")) {  // δυνητικός έλεγχος nullability
            txtName.grabFocus(); rss.warningBox(this, "η ΕΠΩΝΥΜΙΑ ΣΥΓΚΡΟΤΗΜΑΤΟΣ δεν μπορεί να είναι κενή    "); return false; }
        // έλεγχοι για το FormationDate
        if(!mm.getExpertMode() && rss.validateDate(txtFormationDate.getText(), dateRenderer) == null) { txtFormationDate.grabFocus(); rss.infoBox(this, "Η ημερομηνία δεν είναι έγκυρη"); return false; }  // όχι ExpertMode και μη έγκυρη ημερομηνία
        else { mg.setFormationdate(rss.validDate(rss.validateDate(txtFormationDate.getText(), dateRenderer), dateRenderer)); }  // αλλιώς αποθήκευση έγκυρα μορφοποιημένης κατά το δοθέν πρότυπο ή σιωπηρά null αν είμαστε σε ExpertMode και δεν είναι έγκυρη
        if(mg.getFormationdate() != null && rss.fieldUnique(this, MusicGroup.class, "formationdate") && searchMusicGroup("formationdate", mg.getFormationdate())) {  // δυνητικός έλεγχος μοναδικότητας με query
            txtFormationDate.grabFocus(); rss.warningBox(this, "η ΗΜΕΡΟΜΗΝΙΑ πρέπει να είναι μοναδική  "); return false; }
        if(mg.getFormationdate() == null && !rss.fieldNullable(this, MusicGroup.class, "formationdate")) {  // δυνητικός έλεγχος nullability
            txtFormationDate.grabFocus(); rss.warningBox(this, "η ΗΜΕΡΟΜΗΝΙΑ δεν μπορεί να είναι κενή  "); return false; }
        // έλεγχος πλήθους Καλλιτεχνών
        if(listArtistsInMusicGroup == null || listArtistsInMusicGroup.size() < minimumArtists) {  // απαίτηση για τουλάχιστον minimumArtists Καλλιτέχνες σε κάθε Συγκρότημα
            cboxArtist.grabFocus(); rss.warningBox(this, "το ελάχιστο πλήθος ΚΑΛΛΙΤΕΧΝΩΝ είναι " + minimumArtists + "   "); return false;
        } else {
            if(mg.getArtistCollection() == null)  // αν η λίστα Καλλιτεχνών του mg είναι null, δημιούργησε νέα empty list
                mg.setArtistCollection(org.jdesktop.observablecollections.ObservableCollections.observableList(new ArrayList<Artist>()));
            else mg.getArtistCollection().clear();  // αλλιώς μηδένισε πρώτα την ήδη υπάρχουσα και
            mg.getArtistCollection().addAll(listArtistsInMusicGroup); // κάνε την αντιγραφή
        }
        return true; // επιτέλους, όλα ΟΚ!
    }
    
    /* ενεργοποίηση/απενεργοποίηση επιθυμητών components */
    // buttons και components εκτός από jTable και jPanel εκ κατασκευής non-focusable, επιλεκτικό components enabling και focusing
    private void EnableDisableFields(Boolean flag) {
        // για τον πίνακα Συγκροτημάτων και σχετικών κουμπιών
        //jScrollPaneMAINTABLE.getVerticalScrollBar().setEnabled(!flag);
        jScrollPaneMAINTABLE.setEnabled(!flag); jLabelMAINTABLE.setEnabled(!flag);
        jButtonADD.setEnabled(!flag); jButtonEDIT.setEnabled(!flag); jButtonREMOVE.setEnabled(!flag);
        MusicGroupTABLE.setEnabled(!flag); MusicGroupTABLE.getTableHeader().setEnabled(!flag);
        MusicGroupTABLE.setFocusable(!flag);  // reset/set focus στο jTable
        // για τα πεδία επεξεργασίας Συγκροτήματος, πίνακα Καλλιτεχνών και σχετικών κουμπιών
        //jScrollPaneFORM.getVerticalScrollBar().setEnabled(flag);
        jScrollPaneFORM.setEnabled(flag); ArtistsTABLE.setEnabled(flag);
        jButtonSAVE.setEnabled(flag); jButtonCANCEL.setEnabled(flag);
        for (Component c : jPanelFORM.getComponents()) c.setEnabled(flag);
        jLabelFORM.setEnabled(flag); jPanelFORM.setEnabled(flag);  // τελευταίο το jPanel
        jPanelFORM.setFocusable(flag);  // set/reset focus στο jPanel
        jLabelARTISTmale.setEnabled(flag); jLabelARTISTfemale.setEnabled(flag);  // άρρεν ή θήλυ
        // επιπλέον στοιχεία ή κουμπιά προσθήκης/αφαίρεσης μέλους, αρχικά πάντα απενεργοποιημένα
        ArtistsTABLE.setFocusable(false); jButtonADDMEMBER.setEnabled(false); jButtonREMOVEMEMBER.setEnabled(false);
        fieldFocused = 0; editStatus = flag;  // set/reset κατάσταση επεξεργασίας
    }
    
    /* overrides τον default τρόπο rendering σε comboBox με δυνατότητα επιλογής πεδίου από object λίστας */
    // usage: drag&drop class ή στο post-preation code του πίνακα προσθέτω [jComboBox name].setRenderer(new MusicGenreNameRenderer());
    private class ArtistFieldsRenderer extends DefaultListCellRenderer {
        @Override
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
            super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
            if((value != null) && (value instanceof Artist)) {
                Artist artist = (Artist) value;
                setText(artist.getArtisticname());
            }
            return this;
        }
    }
    
    
    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        bindingGroup = new org.jdesktop.beansbinding.BindingGroup();

        try {
            queryMusicGroup = java.beans.Beans.isDesignTime() ? null : em.createQuery("SELECT mg FROM MusicGroup mg");
            listMusicGroup = java.beans.Beans.isDesignTime() ? java.util.Collections.emptyList() : org.jdesktop.observablecollections.ObservableCollections.observableList(queryMusicGroup.getResultList());
        } catch(Exception ex) {
            rss.warningBox(this, "σφάλμα κατά την ανάγνωση MUSICGROUPs");
            // αν υπάρχει προηγούμενη την μηδενίζω και την στέλνω στον GC, κατόπιν δημιουργώ και επιστρέφω νέα κενή λίστα λόγω γενικότερου σφάλματος
            if(listMusicGroup != null) listMusicGroup.clear(); listMusicGroup = null; listMusicGroup = org.jdesktop.observablecollections.ObservableCollections.observableList(new ArrayList<MusicGroup>());
        }
        try {
            queryArtist = java.beans.Beans.isDesignTime() ? null : em.createQuery("SELECT a FROM Artist a");
            listArtist = java.beans.Beans.isDesignTime() ? java.util.Collections.emptyList() : org.jdesktop.observablecollections.ObservableCollections.observableList(queryArtist.getResultList());
        } catch(Exception ex) {
            rss.warningBox(this, "σφάλμα κατά την ανάγνωση ARTISTs");
            // αν υπάρχει προηγούμενη την μηδενίζω και την στέλνω στον GC, κατόπιν δημιουργώ και επιστρέφω νέα κενή λίστα λόγω γενικότερου σφάλματος
            if(listArtist != null) listArtist.clear(); listArtist = null; listArtist = org.jdesktop.observablecollections.ObservableCollections.observableList(new ArrayList<Artist>());
        }
        // ταξινόμηση λίστας Καλλιτεχνών ως προς ArtisticName
        Collections.sort(listArtist, new Comparator<Artist>() {
            @Override
            public int compare(Artist artist1, Artist artist2) {
                return  artist1.getArtisticname().compareTo(artist2.getArtisticname());  // αύξουσα διάταξη
            }
        });
        listArtist.add(0, new Artist("?"));  // προσθέτω και το ? για πιθανή null επιλογή
        try {
            queryArtistsInMusicGroup = java.beans.Beans.isDesignTime() ? null : em.createQuery("SELECT a FROM Artist a WHERE a IS NULL");
            listArtistsInMusicGroup = java.beans.Beans.isDesignTime() ? java.util.Collections.emptyList() : org.jdesktop.observablecollections.ObservableCollections.observableList(queryArtistsInMusicGroup.getResultList());
        } catch(Exception ex) {
            rss.warningBox(this, "σφάλμα κατά την ανάγνωση ARTISTs");
            // αν υπάρχει προηγούμενη την μηδενίζω και την στέλνω στον GC, κατόπιν δημιουργώ και επιστρέφω νέα κενή λίστα λόγω γενικότερου σφάλματος
            if(listArtistsInMusicGroup != null) listArtistsInMusicGroup.clear(); listArtistsInMusicGroup = null; listArtistsInMusicGroup = org.jdesktop.observablecollections.ObservableCollections.observableList(new ArrayList<Artist>());
        }
        jLabelRSTEAM = new javax.swing.JLabel();
        jLabelRSSLOGO = new javax.swing.JLabel();
        jSeparatorLINE = new javax.swing.JSeparator();
        jLabelMAINTABLE = new javax.swing.JLabel();
        jScrollPaneMAINTABLE = new javax.swing.JScrollPane();
        MusicGroupTABLE = new javax.swing.JTable();
        MusicGroupTABLE.setSelectionModel(new MainMenu.ForcedListSelectionModel());

        MusicGroupTABLE.getTableHeader().addMouseListener(new MainMenu.TableHeaderMouseListener(MusicGroupTABLE));
        jLabelFORM = new javax.swing.JLabel();
        jPanelFORM = new javax.swing.JPanel();
        txtName = new javax.swing.JTextField();
        txtFormationDate = new javax.swing.JTextField();
        cboxArtist = new javax.swing.JComboBox();
        cboxArtist.setRenderer(new ArtistFieldsRenderer());
        jScrollPaneFORM = new javax.swing.JScrollPane();
        ArtistsTABLE = new javax.swing.JTable();
        ArtistsTABLE.setSelectionModel(new MainMenu.ForcedListSelectionModel());

        ArtistsTABLE.getTableHeader().addMouseListener(new MainMenu.TableHeaderMouseListener(ArtistsTABLE));
        jButtonADDMEMBER = new javax.swing.JButton();
        jButtonREMOVEMEMBER = new javax.swing.JButton();
        jLabelARTISTfemale = new javax.swing.JLabel();
        jLabelARTISTmale = new javax.swing.JLabel();
        jButtonRETURN = new javax.swing.JButton();
        jButtonADD = new javax.swing.JButton();
        jButtonEDIT = new javax.swing.JButton();
        jButtonREMOVE = new javax.swing.JButton();
        jButtonSAVE = new javax.swing.JButton();
        jButtonCANCEL = new javax.swing.JButton();
        jLabelBACKGROUND = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
        setTitle("RADIO STATION SYSTEM - Διαχείριση Συγκροτημάτων");
        setLocationByPlatform(true);
        setMinimumSize(new java.awt.Dimension(806, 604));
        setName("GROUPsMANAGEMENT"); // NOI18N
        setResizable(false);
        addWindowFocusListener(new java.awt.event.WindowFocusListener() {
            public void windowGainedFocus(java.awt.event.WindowEvent evt) {
                formWindowGainedFocus(evt);
            }
            public void windowLostFocus(java.awt.event.WindowEvent evt) {
            }
        });
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosed(java.awt.event.WindowEvent evt) {
                formWindowClosed(evt);
            }
            public void windowClosing(java.awt.event.WindowEvent evt) {
                formWindowClosing(evt);
            }
            public void windowOpened(java.awt.event.WindowEvent evt) {
                formWindowOpened(evt);
            }
        });
        getContentPane().setLayout(null);

        jLabelRSTEAM.setIcon(new javax.swing.ImageIcon(getClass().getResource("/misc/design/RSTeam_maxi.png"))); // NOI18N
        jLabelRSTEAM.setFocusable(false);
        getContentPane().add(jLabelRSTEAM);
        jLabelRSTEAM.setBounds(516, 533, 284, 43);

        jLabelRSSLOGO.setIcon(new javax.swing.ImageIcon(getClass().getResource("/misc/design/RSS-Logo_maxi.png"))); // NOI18N
        jLabelRSSLOGO.setFocusable(false);
        getContentPane().add(jLabelRSSLOGO);
        jLabelRSSLOGO.setBounds(12, 12, 180, 152);

        jSeparatorLINE.setAutoscrolls(true);
        getContentPane().add(jSeparatorLINE);
        jSeparatorLINE.setBounds(10, 534, 780, 2);

        jLabelMAINTABLE.setFont(new java.awt.Font("Arial", 1, 14)); // NOI18N
        jLabelMAINTABLE.setLabelFor(jScrollPaneMAINTABLE);
        jLabelMAINTABLE.setText("   ΠΙΝΑΚΑΣ ΣΥΓΚΡΟΤΗΜΑΤΩΝ");
        jLabelMAINTABLE.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        jLabelMAINTABLE.setFocusable(false);
        jLabelMAINTABLE.setMaximumSize(new java.awt.Dimension(180, 20));
        jLabelMAINTABLE.setMinimumSize(new java.awt.Dimension(180, 20));
        jLabelMAINTABLE.setOpaque(true);
        jLabelMAINTABLE.setPreferredSize(new java.awt.Dimension(180, 20));
        jLabelMAINTABLE.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jLabelMAINTABLEMouseClicked(evt);
            }
        });
        getContentPane().add(jLabelMAINTABLE);
        jLabelMAINTABLE.setBounds(280, 30, 220, 20);

        jScrollPaneMAINTABLE.setFocusable(false);
        jScrollPaneMAINTABLE.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        jScrollPaneMAINTABLE.setMinimumSize(new java.awt.Dimension(31, 31));
        jScrollPaneMAINTABLE.setPreferredSize(new java.awt.Dimension(490, 183));

        MusicGroupTABLE.setAutoCreateRowSorter(true);
        MusicGroupTABLE.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        MusicGroupTABLE.setMaximumSize(new java.awt.Dimension(2147483647, 0));
        MusicGroupTABLE.setMinimumSize(new java.awt.Dimension(332, 0));

        org.jdesktop.swingbinding.JTableBinding jTableBinding = org.jdesktop.swingbinding.SwingBindings.createJTableBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, listMusicGroup, MusicGroupTABLE);
        org.jdesktop.swingbinding.JTableBinding.ColumnBinding columnBinding = jTableBinding.addColumnBinding(org.jdesktop.beansbinding.ELProperty.create("${name}"));
        columnBinding.setColumnName("ΕΠΩΝΥΜΙΑ ΣΥΓΚΡΟΤΗΜΑΤΟΣ");
        columnBinding.setColumnClass(String.class);
        columnBinding.setEditable(false);
        columnBinding = jTableBinding.addColumnBinding(org.jdesktop.beansbinding.ELProperty.create("${formationdate}"));
        columnBinding.setColumnName("ΗΜ/ΝΙΑ ΔΗΜΙΟΥΡΓΙΑΣ");
        columnBinding.setColumnClass(java.util.Date.class);
        columnBinding.setEditable(false);
        bindingGroup.addBinding(jTableBinding);
        jTableBinding.bind();
        MusicGroupTABLE.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                MusicGroupTABLEMouseClicked(evt);
            }
            public void mousePressed(java.awt.event.MouseEvent evt) {
                MusicGroupTABLEMousePressed(evt);
            }
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                MusicGroupTABLEMouseReleased(evt);
            }
        });
        MusicGroupTABLE.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                MusicGroupTABLEKeyPressed(evt);
            }
            public void keyReleased(java.awt.event.KeyEvent evt) {
                MusicGroupTABLEKeyReleased(evt);
            }
        });
        jScrollPaneMAINTABLE.setViewportView(MusicGroupTABLE);
        if (MusicGroupTABLE.getColumnModel().getColumnCount() > 0) {
            MusicGroupTABLE.getColumnModel().getColumn(0).setMinWidth(189);
            MusicGroupTABLE.getColumnModel().getColumn(1).setMinWidth(143);
            MusicGroupTABLE.getColumnModel().getColumn(1).setPreferredWidth(143);
            MusicGroupTABLE.getColumnModel().getColumn(1).setMaxWidth(143);
            MusicGroupTABLE.getColumnModel().getColumn(1).setCellRenderer(new MainMenu.DateCellRenderer());
        }

        getContentPane().add(jScrollPaneMAINTABLE);
        jScrollPaneMAINTABLE.setBounds(270, 50, 490, 183);

        jLabelFORM.setFont(new java.awt.Font("Arial", 1, 14)); // NOI18N
        jLabelFORM.setLabelFor(jPanelFORM);
        jLabelFORM.setText("   ΣΤΟΙΧΕΙΑ ΣΥΓΚΡΟΤΗΜΑΤΟΣ");
        jLabelFORM.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        jLabelFORM.setEnabled(false);
        jLabelFORM.setFocusable(false);
        jLabelFORM.setMaximumSize(new java.awt.Dimension(180, 20));
        jLabelFORM.setMinimumSize(new java.awt.Dimension(180, 180));
        jLabelFORM.setOpaque(true);
        jLabelFORM.setPreferredSize(new java.awt.Dimension(180, 20));
        getContentPane().add(jLabelFORM);
        jLabelFORM.setBounds(50, 270, 220, 20);

        jPanelFORM.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        jPanelFORM.setEnabled(false);
        jPanelFORM.setPreferredSize(new java.awt.Dimension(720, 180));
        jPanelFORM.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                jPanelFORMFocusGained(evt);
            }
        });
        jPanelFORM.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                jPanelFORMKeyPressed(evt);
            }
        });

        txtName.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        txtName.setBorder(javax.swing.BorderFactory.createTitledBorder("ΕΠΩΝΥΜΙΑ ΣΥΓΚΡΟΤΗΜΑΤΟΣ"));
        txtName.setEnabled(false);
        txtName.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                txtNameActionPerformed(evt);
            }
        });
        txtName.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                txtNameFocusGained(evt);
            }
            public void focusLost(java.awt.event.FocusEvent evt) {
                txtNameFocusLost(evt);
            }
        });
        txtName.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                txtNameKeyPressed(evt);
            }
        });

        txtFormationDate.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        txtFormationDate.setBorder(javax.swing.BorderFactory.createTitledBorder("ΗΜΕΡΟΜΗΝΙΑ ΔΗΜΙΟΥΡΓΙΑΣ"));
        txtFormationDate.setEnabled(false);
        txtFormationDate.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                txtFormationDateActionPerformed(evt);
            }
        });
        txtFormationDate.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                txtFormationDateFocusGained(evt);
            }
            public void focusLost(java.awt.event.FocusEvent evt) {
                txtFormationDateFocusLost(evt);
            }
        });
        txtFormationDate.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                txtFormationDateKeyPressed(evt);
            }
        });

        cboxArtist.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        cboxArtist.setMaximumRowCount(10);
        cboxArtist.setBorder(javax.swing.BorderFactory.createTitledBorder("ΛΙΣΤΑ ΚΑΛΛΙΤΕΧΝΩΝ"));
        cboxArtist.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
        cboxArtist.setEnabled(false);
        cboxArtist.setMinimumSize(new java.awt.Dimension(80, 40));
        cboxArtist.setPreferredSize(new java.awt.Dimension(80, 42));

        org.jdesktop.swingbinding.JComboBoxBinding jComboBoxBinding = org.jdesktop.swingbinding.SwingBindings.createJComboBoxBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, listArtist, cboxArtist);
        bindingGroup.addBinding(jComboBoxBinding);

        cboxArtist.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cboxArtistActionPerformed(evt);
            }
        });
        cboxArtist.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                cboxArtistFocusGained(evt);
            }
        });
        cboxArtist.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                cboxArtistKeyPressed(evt);
            }
        });

        jScrollPaneFORM.setBorder(javax.swing.BorderFactory.createTitledBorder("ΜΕΛΗ ΣΥΓΚΡΟΤΗΜΑΤΟΣ"));
        jScrollPaneFORM.setFocusable(false);
        jScrollPaneFORM.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        jScrollPaneFORM.setMinimumSize(new java.awt.Dimension(31, 31));
        jScrollPaneFORM.setPreferredSize(new java.awt.Dimension(462, 107));

        ArtistsTABLE.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        ArtistsTABLE.setEnabled(false);
        ArtistsTABLE.setFocusable(false);
        ArtistsTABLE.setShowHorizontalLines(false);

        jTableBinding = org.jdesktop.swingbinding.SwingBindings.createJTableBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, listArtistsInMusicGroup, ArtistsTABLE);
        columnBinding = jTableBinding.addColumnBinding(org.jdesktop.beansbinding.ELProperty.create("${artisticname}"));
        columnBinding.setColumnName("ΚΑΛΛΙΤΕΧΝΙΚΟ ΨΕΥΔΩΝΥΜΟ");
        columnBinding.setColumnClass(String.class);
        columnBinding.setEditable(false);
        columnBinding = jTableBinding.addColumnBinding(org.jdesktop.beansbinding.ELProperty.create("${firstname}"));
        columnBinding.setColumnName("ΟΝΟΜΑ");
        columnBinding.setColumnClass(String.class);
        columnBinding.setEditable(false);
        columnBinding = jTableBinding.addColumnBinding(org.jdesktop.beansbinding.ELProperty.create("${lastname}"));
        columnBinding.setColumnName("ΕΠΙΘΕΤΟ");
        columnBinding.setColumnClass(String.class);
        columnBinding.setEditable(false);
        columnBinding = jTableBinding.addColumnBinding(org.jdesktop.beansbinding.ELProperty.create("${sex}"));
        columnBinding.setColumnName("Φ");
        columnBinding.setColumnClass(Integer.class);
        columnBinding.setEditable(false);
        bindingGroup.addBinding(jTableBinding);
        jTableBinding.bind();
        ArtistsTABLE.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                ArtistsTABLEMousePressed(evt);
            }
        });
        ArtistsTABLE.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                ArtistsTABLEKeyPressed(evt);
            }
        });
        jScrollPaneFORM.setViewportView(ArtistsTABLE);
        if (ArtistsTABLE.getColumnModel().getColumnCount() > 0) {
            ArtistsTABLE.getColumnModel().getColumn(0).setMinWidth(186);
            ArtistsTABLE.getColumnModel().getColumn(1).setMinWidth(68);
            ArtistsTABLE.getColumnModel().getColumn(2).setMinWidth(78);
            ArtistsTABLE.getColumnModel().getColumn(3).setMinWidth(24);
            ArtistsTABLE.getColumnModel().getColumn(3).setPreferredWidth(24);
            ArtistsTABLE.getColumnModel().getColumn(3).setMaxWidth(24);
            ArtistsTABLE.getColumnModel().getColumn(3).setCellRenderer(new MainMenu.SexCellRenderer());
        }

        jButtonADDMEMBER.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        jButtonADDMEMBER.setIcon(new javax.swing.ImageIcon(getClass().getResource("/misc/design/_Plus.png"))); // NOI18N
        jButtonADDMEMBER.setText("Προσθήκη");
        jButtonADDMEMBER.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        jButtonADDMEMBER.setEnabled(false);
        jButtonADDMEMBER.setFocusable(false);
        jButtonADDMEMBER.setIconTextGap(8);
        jButtonADDMEMBER.setInheritsPopupMenu(true);
        jButtonADDMEMBER.setMargin(new java.awt.Insets(2, 0, 2, 0));
        jButtonADDMEMBER.setMaximumSize(new java.awt.Dimension(100, 30));
        jButtonADDMEMBER.setMinimumSize(new java.awt.Dimension(100, 30));
        jButtonADDMEMBER.setPreferredSize(new java.awt.Dimension(100, 30));
        jButtonADDMEMBER.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonADDMEMBERActionPerformed(evt);
            }
        });

        jButtonREMOVEMEMBER.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        jButtonREMOVEMEMBER.setIcon(new javax.swing.ImageIcon(getClass().getResource("/misc/design/_Minus.png"))); // NOI18N
        jButtonREMOVEMEMBER.setText("Αφαίρεση");
        jButtonREMOVEMEMBER.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        jButtonREMOVEMEMBER.setEnabled(false);
        jButtonREMOVEMEMBER.setFocusable(false);
        jButtonREMOVEMEMBER.setIconTextGap(8);
        jButtonREMOVEMEMBER.setInheritsPopupMenu(true);
        jButtonREMOVEMEMBER.setMargin(new java.awt.Insets(2, 0, 2, 0));
        jButtonREMOVEMEMBER.setMaximumSize(new java.awt.Dimension(100, 30));
        jButtonREMOVEMEMBER.setMinimumSize(new java.awt.Dimension(100, 30));
        jButtonREMOVEMEMBER.setPreferredSize(new java.awt.Dimension(100, 30));
        jButtonREMOVEMEMBER.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonREMOVEMEMBERActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanelFORMLayout = new javax.swing.GroupLayout(jPanelFORM);
        jPanelFORM.setLayout(jPanelFORMLayout);
        jPanelFORMLayout.setHorizontalGroup(
            jPanelFORMLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanelFORMLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanelFORMLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(jScrollPaneFORM, javax.swing.GroupLayout.DEFAULT_SIZE, 470, Short.MAX_VALUE)
                    .addComponent(txtName))
                .addGap(18, 18, 18)
                .addGroup(jPanelFORMLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addGroup(jPanelFORMLayout.createSequentialGroup()
                        .addComponent(jButtonREMOVEMEMBER, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButtonADDMEMBER, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addComponent(cboxArtist, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(txtFormationDate))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        jPanelFORMLayout.setVerticalGroup(
            jPanelFORMLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelFORMLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanelFORMLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(txtName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(txtFormationDate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 12, Short.MAX_VALUE)
                .addGroup(jPanelFORMLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jScrollPaneFORM, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(jPanelFORMLayout.createSequentialGroup()
                        .addComponent(cboxArtist, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addGroup(jPanelFORMLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jButtonREMOVEMEMBER, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jButtonADDMEMBER, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))
                .addContainerGap(14, Short.MAX_VALUE))
        );

        getContentPane().add(jPanelFORM);
        jPanelFORM.setBounds(40, 290, 720, 190);

        jLabelARTISTfemale.setIcon(new javax.swing.ImageIcon(getClass().getResource("/misc/design/~ArtistFemale.png"))); // NOI18N
        jLabelARTISTfemale.setVerticalAlignment(javax.swing.SwingConstants.TOP);
        jLabelARTISTfemale.setEnabled(false);
        jLabelARTISTfemale.setFocusable(false);
        jLabelARTISTfemale.setMaximumSize(new java.awt.Dimension(0, 0));
        jLabelARTISTfemale.setMinimumSize(new java.awt.Dimension(0, 0));
        getContentPane().add(jLabelARTISTfemale);
        jLabelARTISTfemale.setBounds(70, 170, 120, 110);

        jLabelARTISTmale.setIcon(new javax.swing.ImageIcon(getClass().getResource("/misc/design/~ArtistMale.png"))); // NOI18N
        jLabelARTISTmale.setVerticalAlignment(javax.swing.SwingConstants.TOP);
        jLabelARTISTmale.setEnabled(false);
        jLabelARTISTmale.setFocusable(false);
        jLabelARTISTmale.setMaximumSize(new java.awt.Dimension(0, 0));
        jLabelARTISTmale.setMinimumSize(new java.awt.Dimension(0, 0));
        getContentPane().add(jLabelARTISTmale);
        jLabelARTISTmale.setBounds(140, 160, 120, 120);

        jButtonRETURN.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        jButtonRETURN.setIcon(new javax.swing.ImageIcon(getClass().getResource("/misc/design/_Return.png"))); // NOI18N
        jButtonRETURN.setText("Επιστροφή");
        jButtonRETURN.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        jButtonRETURN.setFocusable(false);
        jButtonRETURN.setIconTextGap(8);
        jButtonRETURN.setMargin(new java.awt.Insets(2, 0, 2, 0));
        jButtonRETURN.setMaximumSize(new java.awt.Dimension(100, 30));
        jButtonRETURN.setMinimumSize(new java.awt.Dimension(100, 30));
        jButtonRETURN.setPreferredSize(new java.awt.Dimension(110, 30));
        jButtonRETURN.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonRETURNActionPerformed(evt);
            }
        });
        getContentPane().add(jButtonRETURN);
        jButtonRETURN.setBounds(40, 541, 110, 30);

        jButtonADD.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        jButtonADD.setIcon(new javax.swing.ImageIcon(getClass().getResource("/misc/design/_Add.png"))); // NOI18N
        jButtonADD.setText("Εισαγωγή");
        jButtonADD.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        jButtonADD.setFocusable(false);
        jButtonADD.setIconTextGap(12);
        jButtonADD.setInheritsPopupMenu(true);
        jButtonADD.setMargin(new java.awt.Insets(2, 0, 2, 0));
        jButtonADD.setMaximumSize(new java.awt.Dimension(100, 30));
        jButtonADD.setMinimumSize(new java.awt.Dimension(100, 30));
        jButtonADD.setPreferredSize(new java.awt.Dimension(100, 30));
        jButtonADD.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonADDActionPerformed(evt);
            }
        });
        getContentPane().add(jButtonADD);
        jButtonADD.setBounds(420, 243, 100, 30);

        jButtonEDIT.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        jButtonEDIT.setIcon(new javax.swing.ImageIcon(getClass().getResource("/misc/design/_Edit.png"))); // NOI18N
        jButtonEDIT.setText("Επεξεργασία");
        jButtonEDIT.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        jButtonEDIT.setFocusable(false);
        jButtonEDIT.setIconTextGap(12);
        jButtonEDIT.setInheritsPopupMenu(true);
        jButtonEDIT.setMargin(new java.awt.Insets(2, 0, 2, 0));
        jButtonEDIT.setMaximumSize(new java.awt.Dimension(120, 30));
        jButtonEDIT.setMinimumSize(new java.awt.Dimension(120, 30));
        jButtonEDIT.setPreferredSize(new java.awt.Dimension(120, 30));
        jButtonEDIT.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonEDITActionPerformed(evt);
            }
        });
        getContentPane().add(jButtonEDIT);
        jButtonEDIT.setBounds(530, 243, 120, 30);

        jButtonREMOVE.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        jButtonREMOVE.setIcon(new javax.swing.ImageIcon(getClass().getResource("/misc/design/_Remove.png"))); // NOI18N
        jButtonREMOVE.setText("Διαγραφή");
        jButtonREMOVE.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        jButtonREMOVE.setFocusable(false);
        jButtonREMOVE.setIconTextGap(12);
        jButtonREMOVE.setInheritsPopupMenu(true);
        jButtonREMOVE.setMargin(new java.awt.Insets(2, 0, 2, 0));
        jButtonREMOVE.setMaximumSize(new java.awt.Dimension(100, 30));
        jButtonREMOVE.setMinimumSize(new java.awt.Dimension(100, 30));
        jButtonREMOVE.setPreferredSize(new java.awt.Dimension(100, 30));
        jButtonREMOVE.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonREMOVEActionPerformed(evt);
            }
        });
        getContentPane().add(jButtonREMOVE);
        jButtonREMOVE.setBounds(660, 243, 100, 30);

        jButtonSAVE.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        jButtonSAVE.setIcon(new javax.swing.ImageIcon(getClass().getResource("/misc/design/_Check.png"))); // NOI18N
        jButtonSAVE.setText("Αποθήκευση");
        jButtonSAVE.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        jButtonSAVE.setEnabled(false);
        jButtonSAVE.setFocusable(false);
        jButtonSAVE.setIconTextGap(12);
        jButtonSAVE.setInheritsPopupMenu(true);
        jButtonSAVE.setMargin(new java.awt.Insets(2, 0, 2, 0));
        jButtonSAVE.setMaximumSize(new java.awt.Dimension(120, 30));
        jButtonSAVE.setMinimumSize(new java.awt.Dimension(120, 30));
        jButtonSAVE.setPreferredSize(new java.awt.Dimension(120, 30));
        jButtonSAVE.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonSAVEActionPerformed(evt);
            }
        });
        getContentPane().add(jButtonSAVE);
        jButtonSAVE.setBounds(530, 490, 120, 30);

        jButtonCANCEL.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        jButtonCANCEL.setIcon(new javax.swing.ImageIcon(getClass().getResource("/misc/design/_Cancel.png"))); // NOI18N
        jButtonCANCEL.setText("Ακύρωση");
        jButtonCANCEL.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        jButtonCANCEL.setEnabled(false);
        jButtonCANCEL.setFocusable(false);
        jButtonCANCEL.setIconTextGap(12);
        jButtonCANCEL.setInheritsPopupMenu(true);
        jButtonCANCEL.setMargin(new java.awt.Insets(2, 0, 2, 0));
        jButtonCANCEL.setMaximumSize(new java.awt.Dimension(100, 30));
        jButtonCANCEL.setMinimumSize(new java.awt.Dimension(100, 30));
        jButtonCANCEL.setPreferredSize(new java.awt.Dimension(100, 30));
        jButtonCANCEL.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonCANCELActionPerformed(evt);
            }
        });
        getContentPane().add(jButtonCANCEL);
        jButtonCANCEL.setBounds(660, 490, 100, 30);

        jLabelBACKGROUND.setIcon(new javax.swing.ImageIcon(getClass().getResource("/misc/design/MICROPHONE_maxi.png"))); // NOI18N
        jLabelBACKGROUND.setFocusable(false);
        jLabelBACKGROUND.setPreferredSize(new java.awt.Dimension(800, 576));
        getContentPane().add(jLabelBACKGROUND);
        jLabelBACKGROUND.setBounds(0, 0, 800, 576);

        bindingGroup.bind();

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void txtNameActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_txtNameActionPerformed
        System.out.println("  ~ActionPerformed name");
        // αν υπάρχουν ανεπιθύμητοι \ χαρακτήρες, grab focus και warningBox
        if(!mm.getExpertMode() && !txtName.getText().equals(txtName.getText().replace("\\",""))) {
            txtName.grabFocus(); rss.infoBox(this, "Δεν επιτρέπονται  \\  σε αλφαριθμητικά"); return;
          // αλλιώς μορφοποίησε το αλφαριθμητικό και σιωπηρά αφαίρεσε τα ανεπιθύμητα \ αν είμαστε σε ExpertMode 
        } else txtName.setText(txtName.getText().replace("\\","").trim());
        // ενδεχόμενος περιορισμός αλφαριθμητικού πεδίου στο μέγεθος που έχει δηλωθεί στο αντίστοιχο POJO
        if(txtName.getText().length() > rss.fieldLength(this, MusicGroup.class, "name")) {
            txtName.setText(txtName.getText().substring(0, rss.fieldLength(this, MusicGroup.class, "name"))); }
        tempTxt = txtName.getText();  // μετά τις μορφοποιήσεις επικαιροποίησε την πρότερη κατάσταση
        // αν η κλήση της μεθόδου δεν προέρχεται από κάποιο focus lost, highlighted επιλογή πεδίου
        if(evt != null) { System.out.println("   ~selectAll"); txtName.selectAll(); }
    }//GEN-LAST:event_txtNameActionPerformed

    private void txtNameFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtNameFocusLost
        System.out.println("  ~FocusLost name");
        if(editStatus && !evt.isTemporary()) {  // αν όχι προσωρινό focus lost
            txtNameActionPerformed(null); fieldFocused = 0;  // έλεγχος εγκυρότητας του αλφαριθμητικού μέσω txtNameActionPerformed
            System.out.println("   ~gotoActionPerformed & focused:0");
        }
    }//GEN-LAST:event_txtNameFocusLost

    private void txtNameFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtNameFocusGained
        System.out.println("  ~FocusGained name " + fieldFocused);
        if(fieldFocused == 0) {  // αν δεν είναι ήδη focused πεδίο
            // clear επιλεγμένης γραμμής πίνακα και απενεργοποίηση focus
            ArtistsTABLE.clearSelection(); ArtistsTABLE.setFocusable(false); 
            // απενεργοποίηση κουμπιών προσθήκης/αφαίρεσης μέλους Συγκροτήματος
            jButtonADDMEMBER.setEnabled(false); jButtonREMOVEMEMBER.setEnabled(false);
            // εφόσον δεν πρόκειται για ήδη focused πεδίο, σώσε το προσωρινά και highlighted επιλογή
            tempTxt = txtName.getText(); txtName.selectAll(); fieldFocused = 1;
            System.out.println("   ~selectAll & focused:1");
        }
    }//GEN-LAST:event_txtNameFocusGained

    private void txtNameKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_txtNameKeyPressed
        if(evt.getKeyCode() == 27) {  // αν πατηθεί Escape επαναφορά στην προηγούμενη έγκυρη κατάσταση προσέχοντας και πιθανά nulls
            // αν συνέβησαν αλλαγές στο πεδίο και δεν είναι ήδη ολόκληρο επιλεγμένο
            if(!tempTxt.equals(txtName.getText()) || !tempTxt.equals(txtName.getSelectedText() == null? "" : txtName.getSelectedText())) { 
                // επαναφορά προηγούμενου και highlighted επιλογή
                txtName.setText(tempTxt); txtName.selectAll();
            } else jButtonCANCELActionPerformed(null);  // αλλιώς έξοδος από τη φόρμα επεξεργασίας
        }
    }//GEN-LAST:event_txtNameKeyPressed

    private void txtFormationDateActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_txtFormationDateActionPerformed
        System.out.println("  ~ActionPerformed formationdate");
        if(!mm.getExpertMode() && rss.validateDate(txtFormationDate.getText(), dateRenderer) == null) {  // έλεγχος εγκυρότητας ημερομηνίας
            // όχι επιτρεπτή ημερομηνία, grab focus και warningBox
            txtFormationDate.grabFocus(); rss.infoBox(this, "Η ημερομηνία δεν είναι έγκυρη"); return;
          // αλλιώς μορφοποίησε την καινούρια ημερομηνία κατά το δοθέν πρότυπο ή σιωπηρά empty string αν είμαστε σε ExpertMode και δεν είναι έγκυρη
        } else txtFormationDate.setText(rss.validateDate(txtFormationDate.getText(), dateRenderer) == null? "" : rss.validateDate(txtFormationDate.getText(), dateRenderer));
        tempTxt = txtFormationDate.getText();  // μετά τους ελέγχους και μορφοποιήσεις επικαιροποίησε την πρότερη κατάσταση
        // αν η κλήση της μεθόδου δεν προέρχεται από κάποιο focus lost, highlighted επιλογή πεδίου
        if(evt != null) { System.out.println("   ~selectAll"); txtFormationDate.selectAll(); }
    }//GEN-LAST:event_txtFormationDateActionPerformed

    private void txtFormationDateFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtFormationDateFocusLost
        System.out.println("  ~FocusLost formationdate");
        if(editStatus && !evt.isTemporary()) {  // αν όχι προσωρινό focus lost
            txtFormationDateActionPerformed(null); fieldFocused = 0;  // έλεγχος εγκυρότητας της ημερομηνίας μέσω txtFormationDateActionPerformed
            System.out.println("   ~gotoActionPerformed & focused:0");
        }
    }//GEN-LAST:event_txtFormationDateFocusLost

    private void txtFormationDateFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtFormationDateFocusGained
        System.out.println("  ~FocusGained formationdate " + fieldFocused);
        if(fieldFocused == 0) {  // αν δεν είναι ήδη focused πεδίο
            // clear επιλεγμένης γραμμής πίνακα και απενεργοποίηση focus
            ArtistsTABLE.clearSelection(); ArtistsTABLE.setFocusable(false); 
            // απενεργοποίηση κουμπιών προσθήκης/αφαίρεσης μέλους Συγκροτήματος
            jButtonADDMEMBER.setEnabled(false); jButtonREMOVEMEMBER.setEnabled(false);
            // εφόσον δεν πρόκειται για ήδη focused πεδίο, σώσε το προσωρινά και highlighted επιλογή
            tempTxt = txtFormationDate.getText(); txtFormationDate.selectAll(); fieldFocused = 2;
            System.out.println("   ~selectAll & focused:2");
        }
    }//GEN-LAST:event_txtFormationDateFocusGained

    private void txtFormationDateKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_txtFormationDateKeyPressed
        if(evt.getKeyCode() == 27) {  // αν πατηθεί Escape επαναφορά στην προηγούμενη έγκυρη κατάσταση πρόσέχοντας και πιθανά nulls
            // αν συνέβησαν αλλαγές στο πεδίο και δεν είναι ήδη ολόκληρο επιλεγμένο
            if(!tempTxt.equals(txtFormationDate.getText()) || !tempTxt.equals(txtFormationDate.getSelectedText() == null? "" : txtFormationDate.getSelectedText())) { 
                // επαναφορά προηγούμενου και highlighted επιλογή
                txtFormationDate.setText(tempTxt); txtFormationDate.selectAll();
            } else jButtonCANCELActionPerformed(null);  // αλλιώς έξοδος από τη φόρμα επεξεργασίας
        }
    }//GEN-LAST:event_txtFormationDateKeyPressed
   
    private void formWindowOpened(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowOpened
        ClearAllFields();  // καθαρισμός όλων των πεδίων της φόρμας επεξεργασίας
        System.out.println("~GroupManagement is ON");
    }//GEN-LAST:event_formWindowOpened

    private void formWindowGainedFocus(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowGainedFocus
        // κάθε φορά που επικεντρώνω στο παράθυρο επικαιροποιώ και την επικεφαλίδα του
        if(mm.getExpertMode()) this.setTitle(frameTitle + " (ExpertMode)"); else this.setTitle(frameTitle);
    }//GEN-LAST:event_formWindowGainedFocus

    private void jButtonRETURNActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonRETURNActionPerformed
        System.out.println(" ~ButtonReturn");
        if(editStatus) {
            editStatus = false;  // για προστασία των πεδίων από τυχόν αλλαγές
            // αν έχουν συμβεί αλλαγές και δεν είμαστε σε ExpertMode, επιλογή yokcancelesnoBox για επιστροφή στη φόρμα 
            if(!compareAllFields() && !mm.getExpertMode() && !(rss.okcancelBox(this, "Οι αλλαγές θα χαθούν. Είστε σίγουροι; ") == 0)) {editStatus = true; return; }
        }    
        this.toBack(); dispose();  // στείλε το παράθυρο στο background και κλείσε το GroupManagement
        System.out.println(" ~closing GroupManagement by Button");
    }//GEN-LAST:event_jButtonRETURNActionPerformed

    private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
        System.out.println(" ~ButtonX");
        if(editStatus) {
            editStatus = false;  // για προστασία των πεδίων από τυχόν αλλαγές
            // αν έχουν συμβεί αλλαγές και δεν είμαστε σε ExpertMode, επιλογή okcancelBox για επιστροφή στη φόρμα 
            if(!compareAllFields() && !mm.getExpertMode() && !(rss.okcancelBox(this, "Οι αλλαγές θα χαθούν. Είστε σίγουροι; ") == 0)) {editStatus = true; return; }
        }
        this.toBack(); dispose();  // στείλε το παράθυρο στο background και κλείσε το GroupManagement
        System.out.println(" ~closing GroupManagement by X");
    }//GEN-LAST:event_formWindowClosing

    private void formWindowClosed(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosed
        mm.setEnabled(true);  // έξοδος και ενεργοποίηση της MainMenu
        System.out.println("~GroupManagement is now OFF");
    }//GEN-LAST:event_formWindowClosed

    private void jLabelMAINTABLEMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jLabelMAINTABLEMouseClicked
        if(!editStatus) MusicGroupTABLE.getRowSorter().setSortKeys(null);  // κατάργηση ταξινόμησης
        // εμφάνιση viewport που να περιέχει την επιλεγμένη γραμμή και επικαιροποίηση του πίνακα
        MusicGroupTABLE.scrollRectToVisible(MusicGroupTABLE.getCellRect(MusicGroupTABLE.getSelectedRow(), 0, true));
        MusicGroupTABLE.repaint();
    }//GEN-LAST:event_jLabelMAINTABLEMouseClicked

    private void MusicGroupTABLEKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_MusicGroupTABLEKeyPressed
        //System.out.println(evt.getKeyCode());
        if(evt.getKeyCode() == 32) { evt.setKeyCode(10); }  // επαναχαρτογράφηση Space key στο Enter key
        else if(evt.getKeyCode() == 127) jButtonREMOVEActionPerformed(null);  // ανακατεύθυνση του Delete key
        else if(evt.getKeyCode() == 10) jButtonEDITActionPerformed(null);  // ανακατεύθυνση του Enter key
        MusicGroupTABLEKeyReleased(null);  // ίδιος κώδικας με MusicGroupTABLEKeyReleased
    }//GEN-LAST:event_MusicGroupTABLEKeyPressed

    private void MusicGroupTABLEKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_MusicGroupTABLEKeyReleased
        int row = MusicGroupTABLE.getSelectedRow();
        // έλεγχος επιλογής γραμμής πίνακα Συγκροτημάτων
        if(row != -1) {  // αν ο πίνακας δεν είναι άδειος
            // αντιστοίχιση mg τύπου MusicGroup στην επιλεγμένη γραμμή
            mg = listMusicGroup.get(MusicGroupTABLE.convertRowIndexToModel(row));
            UpdateAllFields();  // ενημέρωση πεδίων φόρμας επεξεργασίας με τις τιμές του επιλεγμένου αντικειμένου
        } else {
            MusicGroupTABLE.clearSelection(); ClearAllFields();  // clear επιλογής και πεδίων
        }
    }//GEN-LAST:event_MusicGroupTABLEKeyReleased

    private void MusicGroupTABLEMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_MusicGroupTABLEMouseClicked
        if(!editStatus) {
            // εξυπηρέτηση single click
            if(evt.getClickCount() == 1) { /*MusicGroupTABLEKeyReleased(null);*/ }  // τίποτα ή εναλλακτικά ίδιος κώδικας με MusicGroupTABLEKeyReleased
            // εξυπηρέτηση double click με μετάβαση σε κατάσταση επεξεργασίας
            else if(evt.getClickCount() == 2) jButtonEDITActionPerformed(null);
        }
    }//GEN-LAST:event_MusicGroupTABLEMouseClicked

    private void MusicGroupTABLEMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_MusicGroupTABLEMouseReleased
        if(!editStatus) {
            MusicGroupTABLEKeyReleased(null);  // ίδιος κώδικας με MusicGroupTABLEKeyReleased
        }
    }//GEN-LAST:event_MusicGroupTABLEMouseReleased

    private void jPanelFORMKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_jPanelFORMKeyPressed
        if(evt.getKeyCode() == 27) jButtonCANCELActionPerformed(null);  // έξοδος από το jPanel με Escape
    }//GEN-LAST:event_jPanelFORMKeyPressed

    private void jButtonADDActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonADDActionPerformed
        if(!editStatus) {  // αν όχι σε κατάστασης επεξεργασίας
            System.out.println(" ~ButtonADD");
            // reset combo boxes to top (το index -1 είναι το null) και καθαρισμός πεδίων
            cboxArtist.setSelectedIndex(0); ClearAllFields();
            // προετοιμασία ενεργών & ανενεργών components για μετάβαση σε κατάσταση επεξεργασίας
            EnableDisableFields(true); jButtonADD.setEnabled(true); jPanelFORM.grabFocus();
            // νέο mg τύπου MusicGroup και κατάσταση επεξεργασίας ADD
            mg = new MusicGroup(); addORedit = true;
            //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
        } else Toolkit.getDefaultToolkit().beep();
    }//GEN-LAST:event_jButtonADDActionPerformed

    private void jButtonEDITActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonEDITActionPerformed
        if(!editStatus) {  // αν όχι σε κατάσταση επεξεργασίας
            System.out.println(" ~ButtonEDIT");
            if(MusicGroupTABLE.getSelectedRow() != -1) {  // και ο πίνακας δεν είναι άδειος
                int row = MusicGroupTABLE.getSelectedRow();  // αποθήκευση επιλεγμένης γραμμής
                // αντιστοίχιση αντικειμένου mg τύπου MusicGroup στην επιλεγμένη γραμμή, προσωρινή αποθήκευση 
                mg = listMusicGroup.get(MusicGroupTABLE.convertRowIndexToModel(row)); CopyAllFields(tempMG, mg);
                if(rss.accessDB(this, mg,"R")) {  // και έλεγχος/επικαιροποίηση των πεδίων του αντικειμένου mg από την ΒΔ as good measure
                    // αν όλα πήγαν καλά, προετοιμασία ενεργών & ανενεργών components και ανανέωση πίνακα Καλλιτεχνών
                    EnableDisableFields(true); jButtonEDIT.setEnabled(true); jPanelFORM.grabFocus(); //ArtistsTABLE.repaint();
                    // νέα προσωρινή αποθήκευση, ενημέρωση πεδίων με τις τιμές του πίνακα Συγκροτημάτων και κατάσταση επεξεργασίας EDIT
                    CopyAllFields(tempMG, mg); UpdateAllFields(); addORedit = false;
                    //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
                } else {  // αν όμως συμβεί σφάλμά κατά τον έλεγχος/επικαιροποίηση των πεδίων του αντικειμένου mg από την ΒΔ
                    // εκ νέου αντιστοίχιση αντικειμένου mg τύπου MusicGroup στην επιλεγμένη γραμμή και επαναφορά
                    mg = listMusicGroup.get(MusicGroupTABLE.convertRowIndexToModel(row)); CopyAllFields(mg, tempMG);
                    UpdateAllFields(); addORedit = null;  // ενημέρωση πεδίων με τις τιμές του πίνακα
                    //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                }
            } else {  // αλλιώς αν ο πίνακας είναι άδειος
                MusicGroupTABLE.clearSelection(); ClearAllFields();  // clear επιλογής πίνακα και πεδίων
                Toolkit.getDefaultToolkit().beep();
                //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
            }
        } else Toolkit.getDefaultToolkit().beep();
    }//GEN-LAST:event_jButtonEDITActionPerformed

    private void jButtonREMOVEActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonREMOVEActionPerformed
        System.out.println(" ~ButtonREMOVE");
        if(MusicGroupTABLE.getSelectedRow() != -1) {  // αν ο πίνακας δεν είναι άδειος
            int row = MusicGroupTABLE.getSelectedRow();  // αποθήκευση επιλεγμένης γραμμής
            if(!mm.getExpertMode() && !(rss.okcancelBox(this, "Η επιλεγμένη γραμμή θα διαγραφεί. Είστε σίγουροι;  ") == 0)) return;
                //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
            // αντιστοίχιση αντικειμένου mg τύπου MusicGroup στην επιλεγμένη γραμμή του πίνακα, προσωρινή αποθήκευση
            mg = listMusicGroup.get(MusicGroupTABLE.convertRowIndexToModel(row)); CopyAllFields(tempMG, mg);
            if(rss.accessDB(this, mg,"R")) {  // έλεγχος ύπαρξής/επικαιροποίηση as good measure του αντικειμένου mg από την ΒΔ
                CopyAllFields(tempMG, mg);  // εκ νέου προσωρινή αποθήκευση πιθανώς επικαιροποιημένου αντικειμένου από προηγουμένως
                if(rss.accessDB(this, mg,"D")) {  // διαγραφή του αντικειμένου mg από την ΒΔ
                    // όλα καλά, διαγραφή αντικειμένου mg τύπου MusicGroup από τους Καλλιτέχνες που ενδεχομένως συμμετείχαν σε αυτό
                    for(Artist artist : mg.getArtistCollection()) artist.getMusicGroupCollection().remove(mg);
                    // διαγραφή αντικειμένου mg τύπου MusigGroup από τα Άλμπουμ που ενδεχομένως δημιούργησε
                    for(Album album : mg.getAlbumCollection()) album.setMusicgroupId(null);
                    // διαγραφή αντικειμένου mg και από τη λίστα της φόρμας, νέο mg MusicGroup και το παλιό έτοιμο για GarbageCollector!
                    listMusicGroup.remove(mg); clearMusicGroup(mg); mg = null; mg = new MusicGroup();
                    // επικαιροποίηση επιλογής γραμμής πίνακα Συγκροτημάτων λόγω διαγραφής
                    if(row >= MusicGroupTABLE.getRowCount()) row = MusicGroupTABLE.getRowCount()-1;
                    // έλεγχος επιλογής γραμμής πίνακα Συγκροτημάτων για επικαιροποίηση πεδίων λόγω διαγραφής
                    if(row != -1) {  // αν ο πίνακας που προέκυψε δεν είναι άδειος
                        MusicGroupTABLE.setRowSelectionInterval(row, row);  // επέλεξε την νέα γραμμή
                        mg = listMusicGroup.get(MusicGroupTABLE.convertRowIndexToModel(row));  // αντιστοίχιση mg τύπου MusicGroup στην επιλεγμένη γραμμή 
                        UpdateAllFields();  // ενημέρωση πεδίων με τις τιμές του επιλεγμένου αντικειμένου
                    } else {  // και αν ο πίνακας που προέκυψε είναι άδειος
                        MusicGroupTABLE.clearSelection(); ClearAllFields();  // clear επιλογής πίνακα και πεδίων
                    }
                    // επιλογή νέου viewport και επικαιροποίηση του πίνακα Συγκροτημάτων
                    MusicGroupTABLE.scrollRectToVisible(MusicGroupTABLE.getCellRect(row, 0, true)); //MusicGroupTABLE.repaint();
                    //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
                } else {  // και αν γενικότερα συμβεί κάποιο σφάλμα κατά τη διαγραφή του αντικειμένου mg από την ΒΔ
                    // εκ νέου αντιστοίχιση αντικειμένου mg τύπου MusicGroup στην επιλεγμένη γραμμή και επαναφορά
                    mg = listMusicGroup.get(MusicGroupTABLE.convertRowIndexToModel(row)); CopyAllFields(mg, tempMG);
                    UpdateAllFields();  // ενημέρωση πεδίων με τις τιμές του επιλεγμένου αντικειμένου
                    //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                }
            } else {  // και αν συμβεί σφάλμα κατά τον έλεγχο ύπαρξής/επικαιροποίηση του αντικειμένου mg από την ΒΔ
                // εκ νέου αντιστοίχιση αντικειμένου mg τύπου MusicGroup στην επιλεγμένη γραμμή και επαναφορά
                mg = listMusicGroup.get(MusicGroupTABLE.convertRowIndexToModel(row)); CopyAllFields(mg, tempMG);
                UpdateAllFields();  // ενημέρωση πεδίων με τις τιμές του επιλεγμένου αντικειμένου
                //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
            }
        } else {  // και αν ο πίνακας είναι άδειος
            MusicGroupTABLE.clearSelection(); ClearAllFields();  // clear επιλογής και πεδίων
            Toolkit.getDefaultToolkit().beep();
        }
    }//GEN-LAST:event_jButtonREMOVEActionPerformed

    private void jButtonSAVEActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonSAVEActionPerformed
        System.out.println("  ~ButtonSAVE");
        editStatus = false;  // προστασία των πεδίων από τυχόν αλλαγές
        if(addORedit) {  // αν βρισκόμαστε σε κατάσταση επεξεργασίας ADD
            // επαλήθευση πεδίων και εγγραφή mg στη ΒΔ
            if(validateAllFields() && rss.accessDB(this, mg,"W")) {  // αν η επιβεβαίωση και η εγγραφή γίνουν σωστά
                listMusicGroup.add(mg);  // όλα καλά, προσθήκη του αντικειμένου και στη λίστα
                int row = MusicGroupTABLE.getRowCount()-1;  // κατέγραψε το νέο μέγεθος του πίνακα
                // αποθήκευσε πιθανή κατάσταση ταξινόμησης και κατάργησε το row sorting του πίνακα
                List<? extends SortKey> myList = MusicGroupTABLE.getRowSorter().getSortKeys(); MusicGroupTABLE.getRowSorter().setSortKeys(null);
                MusicGroupTABLE.setRowSelectionInterval(row, row);  //επέλεξε τη νέα γραμμή (τελευταία σε unsorted model) του πίνακα
                // επαναφορά αποθηκευμένης κατάστασης ταξινόμησης και ρύθμιση viewport πίνακα ώστε η νεοεισηγμένη γραμμή να είναι visible
                MusicGroupTABLE.getRowSorter().setSortKeys(myList); MusicGroupTABLE.scrollRectToVisible(MusicGroupTABLE.getCellRect(row, 0, true));
                // αντιστοίχιση αντικειμένου mg τύπου MusicGroup στην επιλεγμένη γραμμή του πίνακα
                mg = listMusicGroup.get(MusicGroupTABLE.convertRowIndexToModel(MusicGroupTABLE.getSelectedRow()));
                // ενημέρωση πεδίων με τις τιμές του επιλεγμένου αντικειμένου και επικαιροποίηση του πίνακα Συγκροτημάτων
                UpdateAllFields(); //MusicGroupTABLE.repaint();
                // προετοιμασία ενεργών & ανενεργών components και reset κατάστασης επεξεργασίας
                EnableDisableFields(false); MusicGroupTABLE.grabFocus(); addORedit = null;
                //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
            } else { clearMusicGroup(mg); mg = null; mg = new MusicGroup(); editStatus = true; }  // κάτι δεν έγινε σωστά, νέο καθαρό MusicGroup mg και πίσω στη φόρμα
        } else {  // και αν βρισκόμαστε σε κατάσταση επεξεργασίας EDIT
            // επαλήθευση πεδίων και ανανέωση mg στη ΒΔ
            if(validateAllFields() && rss.accessDB(this, mg,"U")) { // αν η επιβεβαίωση και η ανανέωση γίνουν σωστά
                // αν όλα καλά, ενημέρωση του αντικειμένου mg και στη λίστα
                listMusicGroup.set(MusicGroupTABLE.convertRowIndexToModel(MusicGroupTABLE.getSelectedRow()), mg);
                // και εκ νέου αντιστοίχιση αντικειμένου mg τύπου MusicGroup στην επιλεγμένη γραμμή του πίνακα
                mg = listMusicGroup.get(MusicGroupTABLE.convertRowIndexToModel(MusicGroupTABLE.getSelectedRow()));
                // ενημέρωση πεδίων με τις τιμές του επιλεγμένου αντικειμένου και επικαιροποίηση του πίνακα Συγκροτημάτων
                UpdateAllFields(); //MusicGroupTABLE.repaint();
                // προετοιμασία ενεργών & ανενεργών components και reset κατάστασης επεξεργασίας
                EnableDisableFields(false); MusicGroupTABLE.grabFocus(); addORedit = null;
                //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
            } else {  // κάτι δεν έγινε σωστά, ξαναδιάβασμα mg από τον πίνακα και πίσω στη φόρμα
                // εκ νέου αντιστοίχιση αντικειμένου mg τύπου MusicGroup στην επιλεγμένη γραμμή του πίνακα
                mg = listMusicGroup.get(MusicGroupTABLE.convertRowIndexToModel(MusicGroupTABLE.getSelectedRow()));
                // και νέος έλεγχος-ανανέωσή των πεδίων του από την ΒΔ
                if(rss.accessDB(this, mg,"R")) {  // αν η νέα ανάγνωση γίνει σωστά
                    CopyAllFields(tempMG, mg); editStatus = true;  // νέα προσωρινή αποθήκευση και πίσω στη φόρμα επεξεργασίας
                    //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                } else {  // το σφάλμα είναι μάλλον σοβαρότερο, πίσω πάλι στον πίνακα    
                    // εκ νέου αντιστοίχιση as good measure αντικειμένου mg τύπου MusicGroup στην επιλεγμένη γραμμή του πίνακα και επαναφορά
                    mg = listMusicGroup.get(MusicGroupTABLE.convertRowIndexToModel(MusicGroupTABLE.getSelectedRow())); CopyAllFields(mg, tempMG);
                    // ενημέρωση πεδίων με τις τιμές του επιλεγμένου αντικειμένου και επικαιροποίηση του πίνακα Συγκροτημάτων
                    UpdateAllFields(); //MusicGroupTABLE.repaint();
                    // προετοιμασία ενεργών & ανενεργών components και reset κατάστασης επεξεργασίας
                    EnableDisableFields(false); MusicGroupTABLE.grabFocus(); addORedit = null;
                    //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                }
            }
        }
    }//GEN-LAST:event_jButtonSAVEActionPerformed

    private void jButtonCANCELActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonCANCELActionPerformed
        System.out.println("  ~ButtonCANCELorESCAPE");
        editStatus = false;  // για προστασία των πεδίων από τυχόν αλλαγές
        // αν έχουν συμβεί αλλαγές και δεν είμαστε σε ExpertMode, επιλογή okcancelBox για επιστροφή στη φόρμα
        if(!compareAllFields() && !mm.getExpertMode() && !(rss.okcancelBox(this, "Οι αλλαγές θα χαθούν. Είστε σίγουροι; ") == 0)) { editStatus = true; return; }
            //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
        // αν ακυρώθηκε ADD το mg που δημιουργήθηκε πριν δεν χρειάζεται παρά μόνο στον GarbageCollector, αλλιώς as good measure επαναφορά προσωρινού
        if(addORedit) { clearMusicGroup(mg); mg = null; mg = new MusicGroup(); } else CopyAllFields(mg, tempMG);
        // τώρα που πλέον η ακύρωση έχει ολοκληρωθεί, πάμε καλόυ κακού για ανανέωση του πίνακα
        if(MusicGroupTABLE.getSelectedRow() != -1)  {  // αν ο πίνακας δεν είναι άδειος
            // αντιστοίχιση αντικειμένου mg τύπου MusicGroup στην επιλεγμένη γραμμή του πίνακα
            mg = listMusicGroup.get(MusicGroupTABLE.convertRowIndexToModel(MusicGroupTABLE.getSelectedRow()));
            UpdateAllFields();  // ενημέρωση πεδίων με τις τιμές του επιλεγμένου αντικειμένου
        } else {  // και αν ο πίνακας είναι άδειος
            MusicGroupTABLE.clearSelection(); ClearAllFields();  // clear επιλογής πίνακα και πεδίων
        }
        // προετοιμασία ενεργών & ανενεργών components και reset κατάστασης επεξεργασίας
        EnableDisableFields(false); MusicGroupTABLE.grabFocus(); addORedit = null;
        //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    }//GEN-LAST:event_jButtonCANCELActionPerformed

    private void cboxArtistActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cboxArtistActionPerformed
        if(editStatus) {
            System.out.println("  ~ActionPerformed artistmember " + fieldFocused);
            cboxArtist.setSelectedIndex(cboxArtist.getSelectedIndex() > 0? cboxArtist.getSelectedIndex() : -1);  // με απορρόφηση του null ?
            if(cboxArtist.getSelectedIndex() > 0) jButtonADDMEMBER.setEnabled(true);  // ενεργοποίηση κουμπιού προσθήκης Καλλιτέχνη
            else jButtonADDMEMBER.setEnabled(false);  // απενεργοποίηση κουμπιού προσθήκης Καλλιτέχνη 
        }
    }//GEN-LAST:event_cboxArtistActionPerformed

    private void jPanelFORMFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jPanelFORMFocusGained
        System.out.println(" ~FocusGained jpanelform " + fieldFocused);
        fieldFocused = 0;
    }//GEN-LAST:event_jPanelFORMFocusGained

    private void cboxArtistKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_cboxArtistKeyPressed
        // αν πατηθεί Escape και δεν είναι ανοικτό το popup menu, έξοδος από τη φόρμα επεξεργασίας
        if(evt.getKeyCode() == 27 && !cboxArtist.isPopupVisible()) jButtonCANCELActionPerformed(null);
    }//GEN-LAST:event_cboxArtistKeyPressed

    private void jButtonADDMEMBERActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonADDMEMBERActionPerformed
        System.out.println("  ~ButtonADDMEMBER");
        if(cboxArtist.getSelectedIndex() > 0) {  // αν είναι κάτι επιλεγμένο στη λίστα Καλλιτεχνών
            if(listArtistsInMusicGroup.contains(cboxArtist.getSelectedItem())) rss.warningBox(this, "ο ΚΑΛΛΙΤΕΧΝΗΣ αυτός είναι ήδη μέλος του ΣΥΓΚΡΟΤΗΜΑΤΟΣ   ");
            else {
                listArtistsInMusicGroup.add((Artist) cboxArtist.getSelectedItem());  // τοποθέτησέ τον στην λίστα του πίνακα
                jButtonADDMEMBER.setEnabled(false);  // απενεργοποίησε το κουμπί προσθήκης Καλλιτέχνη
                cboxArtist.setSelectedIndex(-1);  // και καθαρισμός επιλογής, index -1 είναι το null
                //jPanelFORM.grabFocus();  // focus στο jPanel ή ενναλλακτικά μετάθεση focus στον πίνακα
                int row = ArtistsTABLE.getRowCount()-1;  // κατέγραψε το νέο μέγεθος του πίνακα Καλλιτεχνών
                ArtistsTABLE.setRowSelectionInterval(row, row); ArtistsTABLE.setFocusable(true); ArtistsTABLE.grabFocus();  // επιλογή νέας γραμμής και focus στον πίνακα
                ArtistsTABLE.scrollRectToVisible(ArtistsTABLE.getCellRect(row, 0, true));  // ρύθμιση viewport πίνακα ώστε η νεοεισαχθείσα γραμμή να είναι visible
                jButtonREMOVEMEMBER.setEnabled(true);  // ενεργοποίηση κουμπιού αφαίρεσης Καλλιτέχνη
            }  
        } else Toolkit.getDefaultToolkit().beep();
    }//GEN-LAST:event_jButtonADDMEMBERActionPerformed

    private void jButtonREMOVEMEMBERActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonREMOVEMEMBERActionPerformed
        System.out.println("  ~ButtonREMOVEMEMBER");
        if(ArtistsTABLE.getSelectedRow() != -1) {  // αν ο πίνακας δεν είναι άδειος
            int row = ArtistsTABLE.getSelectedRow();  // αποθήκευση επιλεγμένης γραμμής
            if(!mm.getExpertMode() && !(rss.okcancelBox(this, "Η επιλεγμένη γραμμή θα διαγραφεί. Είστε σίγουροι;  ") == 0)) return;
                //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
            // διαγραφή επιλεγμένου αντικειμένου τύπου Artist από τη λίστα
            listArtistsInMusicGroup.remove(listArtistsInMusicGroup.get(ArtistsTABLE.convertRowIndexToModel(row)));
            // επικαιροποίηση επιλογής γραμμής πίνακα Καλλιτεχνών λόγω διαγραφής γραμμής
            if(row >= ArtistsTABLE.getRowCount()) row = ArtistsTABLE.getRowCount()-1;
            // έλεγχος επιλογής γραμμής πίνακα Καλλιτεχνών για επικαιροποίηση πεδίων λόγω διαγραφής
            if(row != -1) {  // αν ο πίνακας που προέκυψε δεν είναι άδειος
                ArtistsTABLE.setRowSelectionInterval(row, row);  // επέλεξε την νέα γραμμή
            } else {  // αν όμως ο πίνακας που προέκυψε είναι άδειος
                ArtistsTABLE.clearSelection();  // clear επιλογής
            }
            // επιλογή νέου viewport και επικαιροποίηση του πίνακα Καλλιτεχνών
            ArtistsTABLE.scrollRectToVisible(ArtistsTABLE.getCellRect(row, 0, true)); //ArtistsTABLE.repaint();
            //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
        } else {  // και αν ο πίνακας είναι άδειος
            ArtistsTABLE.clearSelection();  // clear επιλογής πίνακα
            Toolkit.getDefaultToolkit().beep();
        }
    }//GEN-LAST:event_jButtonREMOVEMEMBERActionPerformed

    private void ArtistsTABLEKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_ArtistsTABLEKeyPressed
        //System.out.println(evt.getKeyCode());
        if(evt.getKeyCode() == 32) { evt.setKeyCode(10); }  // επαναχαρτογράφηση Space key στο Enter key
        else if(evt.getKeyCode() == 127) jButtonREMOVEMEMBERActionPerformed(null);  // ανακατεύθυνση του Delete key
    }//GEN-LAST:event_ArtistsTABLEKeyPressed

    private void ArtistsTABLEMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_ArtistsTABLEMousePressed
        if(editStatus && !ArtistsTABLE.isFocusable()) {
            ArtistsTABLE.setFocusable(true); ArtistsTABLE.grabFocus();  // focus στον πίνακα
            jButtonREMOVEMEMBER.setEnabled(true);  // ενεργοποίηση κουμπιού αφαίρεσης Καλλιτέχνη
            jButtonADDMEMBER.setEnabled(false);  // απενεργοποίηση κουμπιού προσθήκης Καλλιτέχνη
            cboxArtist.setSelectedIndex(-1);  // και καθαρισμός επιλογής, index -1 είναι το null
        }
    }//GEN-LAST:event_ArtistsTABLEMousePressed

    private void MusicGroupTABLEMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_MusicGroupTABLEMousePressed
        if(!editStatus) {
            MusicGroupTABLEKeyReleased(null);  // ίδιος κώδικας με MusicGroupTABLEKeyReleased
        }
    }//GEN-LAST:event_MusicGroupTABLEMousePressed

    private void cboxArtistFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_cboxArtistFocusGained
        if(!editStatus) {
            // clear επιλεγμένης γραμμής πίνακα, απενεργοποίηση focus πίνακα και κουμπιού αφαίρεσης Καλλιτέχνη
            ArtistsTABLE.clearSelection(); ArtistsTABLE.setFocusable(false); jButtonREMOVEMEMBER.setEnabled(false);
        }
    }//GEN-LAST:event_cboxArtistFocusGained

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JTable ArtistsTABLE;
    private javax.swing.JTable MusicGroupTABLE;
    private javax.swing.JComboBox cboxArtist;
    private javax.swing.JButton jButtonADD;
    private javax.swing.JButton jButtonADDMEMBER;
    private javax.swing.JButton jButtonCANCEL;
    private javax.swing.JButton jButtonEDIT;
    private javax.swing.JButton jButtonREMOVE;
    private javax.swing.JButton jButtonREMOVEMEMBER;
    private javax.swing.JButton jButtonRETURN;
    private javax.swing.JButton jButtonSAVE;
    private javax.swing.JLabel jLabelARTISTfemale;
    private javax.swing.JLabel jLabelARTISTmale;
    private javax.swing.JLabel jLabelBACKGROUND;
    private javax.swing.JLabel jLabelFORM;
    private javax.swing.JLabel jLabelMAINTABLE;
    private javax.swing.JLabel jLabelRSSLOGO;
    private javax.swing.JLabel jLabelRSTEAM;
    private javax.swing.JPanel jPanelFORM;
    private javax.swing.JScrollPane jScrollPaneFORM;
    private javax.swing.JScrollPane jScrollPaneMAINTABLE;
    private javax.swing.JSeparator jSeparatorLINE;
    private java.util.List<Artist> listArtist;
    private java.util.List<Artist> listArtistsInMusicGroup;
    private java.util.List<MusicGroup> listMusicGroup;
    private javax.persistence.Query queryArtist;
    private javax.persistence.Query queryArtistsInMusicGroup;
    private javax.persistence.Query queryMusicGroup;
    private javax.swing.JTextField txtFormationDate;
    private javax.swing.JTextField txtName;
    private org.jdesktop.beansbinding.BindingGroup bindingGroup;
    // End of variables declaration//GEN-END:variables
}